﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SanctusSoftware.Music.ChordSheetEditor.Client;
using Microsoft.Office.Interop.Word;
using System.Text.RegularExpressions;
using SanctusSoftware.Music.Chords;

namespace SanctusSoftware.Music.ChordSheetEditor.Word
{
  public class WordSentence : ISentence
  {

    #region Fields
    private global::System.Object missing = global::System.Type.Missing;
    private readonly Range _Sentence;

    #endregion

    #region Properties

    public object Tag
    {
      get { return _Sentence; }
    }

    public string Text
    {
      get { return _Sentence.Text; }
    }

    private IFont _Font = null;

    public IFont Font
    {
      get
      {
        // This assumes that the _Sentence object always keeps the same instance of Font. It might not, at which point a new WordFont object would have to be built each time
        if (_Font == null)
        {
          _Font = new WordFont(_Sentence.Font);
        }
        return _Font;
      }
    }

    public bool ContainsHyperlinks
    {
      get { return (_Sentence.Hyperlinks.Count > 0); }
    }

    #endregion

    #region Constructor

    public WordSentence(Range sentence)
    {
      _Sentence = sentence;
    }

    #endregion

    #region Methods

    public void RemoveHyperlinks()
    {

      for (int i = _Sentence.Hyperlinks.Count - 1; i >= 0; i--)
      {
        object index = (i + 1);
        Hyperlink hyperlink = _Sentence.Hyperlinks.get_Item(ref index);
        object unit = System.Reflection.Missing.Value; //WdUnits.wdCell;
        object count = System.Reflection.Missing.Value; //(hyperlink.Range.End - hyperlink.Range.Start);
        //hyperlink.Range.Delete(ref unit, ref count);

        // Backup the Hyperlink's Format
        Font font = hyperlink.Range.FormattedText.Font;

        // Font couldn't be determined - try one character before
        if (font.Name == string.Empty && hyperlink.Range.Start > 1)
        {
          object start = hyperlink.Range.Start - 1;
          object end = hyperlink.Range.Start;
          Range temp = hyperlink.Range.Document.Range(ref start, ref end);
          font = temp.Font;
        }

        hyperlink.Range.Text = hyperlink.Range.Text; // Seems to clear the hyperlink

        // Restore the Former-Hyperlink's format
        hyperlink.Range.FormattedText.Font = font;

        //chordSentence.Hyperlinks.get_Item(ref index).
      }


    }

    public void Delete()
    {
      _Sentence.Delete(ref missing, ref missing);
    }

    public IWord[] GetChordWords()
    {

      List<Range> words = new List<Range>();



      if (_Sentence.Hyperlinks.Count > 0)
      {
        throw new ChordSentenceContainsHyperlinksException();
      }

      Match chordMatch = ChordTransposer.FindChordMatch(_Sentence.Text, 0);

      while (chordMatch != null)
      {

        object rangeStart = (_Sentence.Start + chordMatch.Index);
        object rangeEnd = (_Sentence.Start + chordMatch.Index + chordMatch.Value.Length);
        Range chordRange = _Sentence.Document.Range(ref rangeStart, ref rangeEnd);
        words.Add(chordRange);

        // Get the Next Chord Match
        chordMatch = ChordTransposer.FindChordMatch(_Sentence.Text, chordMatch.Index + chordMatch.Value.Length);

      }

      return (from w in words
              select new WordWord(w)).ToArray();

    }

    public IWord[] GetWordsAndPunctuation()
    {

      // Break up EVERYTHING in the sentence
      // Possible Regex: \b.+?\b
      // Has issues with hypenated words
      // Might have to fix that bit manually
      // Try this: ((?:[A-Za-z]+[-][A-Za-z]+)|(?:\b.+?\b))
      //string pattern = @"((?:[A-Za-z]+[-][A-Za-z]+)|(?:\b.+?\b))";
      // Nope! The above won't work for chords like C#m7
      // Need to find a better regex
      //string pattern = @"(?<=[ ,])?[^\s,]*";
      string pattern = @"(?<=[\s,])?[^\s,]*";

      // Amazing grace, how sweet the sound
      // Amazing
      // grace
      // ,
      // how
      // sweet
      // the
      // sound

      // Before Thee on ever-bended knee
      // Before
      // Thee
      // on
      // ever-bended
      // knee

      // 'Tis so sweet to trust in Jesus
      // '
      // Tis
      // so
      // sweet
      // to
      // trust
      // in
      // Jesus

      List<Range> words = new List<Range>();
      
      MatchCollection matches = Regex.Matches(this.Text, pattern);
      foreach (Match match in matches)
      {
        if (!string.IsNullOrEmpty(match.Value.Trim())) // For .NET 4, convert to IsNullOrWhitespace
        {
          object rangeStart = (_Sentence.Start + match.Index);
          object rangeEnd = (_Sentence.Start + match.Index + match.Value.Length);
          Range range = _Sentence.Document.Range(ref rangeStart, ref rangeEnd);
          words.Add(range);
        }
      }

      return (from w in words
              select new WordWord(w)).ToArray();
      
    }

    #endregion













  }
}
